home *** CD-ROM | disk | FTP | other *** search
/ Java Interactive Reference Guide / Java Interactive Reference Guide.iso / autorun / java_d.dir / 00053_introduction.txt < prev    next >
Encoding:
Text File  |  1980-01-11  |  19.3 KB  |  330 lines

  1. Objects
  2.  
  3. What are objects? They're software programming models of objects of everyday life. In your everyday life, you're surrounded by objects--cars, coffee machines, ducks, trees, and so on. These objects have state and behavior. You can model everyday objects with software constructs called objects. Software objects can also be defined by their state and their behavior.
  4.  
  5. In your everyday transportation needs, a car can be modelled by an object. A car has state (how fast it's going, in which direction, its fuel consumption, and so on) and behavior (starts, stops, turns, slides, and runs into trees).
  6.  
  7. In your daily interactions with the financial markets, a call option can also be modelled by an object. A call option has state (current price, strike price, expiration date), and behavior (changes value, moves into and out of the money, or expires worthless).
  8.  
  9. After your call options have expired worthless, you repair to the cafe for a cup of good hot coffee. The espresso machine can be modelled as an object. It has state (water temperature, amount of coffee in the hopper) and it has behavior (emits steam, makes noise, and brews a perfect cup of Java).
  10.  
  11. An important characteristic that distinguishes objects from procedures or functions is that an object can have a lifetime greater than that of the object that created it. This aspect of objects is subtle and mostly overlooked. In the distributed client-server world, this means that objects can be created in one place, passed around networks, and stored elsewhere to be retrieved at later stages for future work.
  12.  
  13.  
  14.  
  15. The Basics of Objects
  16.  
  17. In the implementation of an object, its state is defined by its instance variables. Instance variables are variables local to the object. Unless explicitly made public or made available to other "friendly" classes, they are inaccessible from outside the object. An object's behavior is defined by its methods. Methods manipulate the instance variables to create new state, and can also create new objects. This picture is a commonly used graphical representation of an object. The diagram illustrates the conceptual structure of a software object--it's kind of like a cell, with an outer membrane that's its interface to the world, and an inner nucleus that's protected by the outer membrane.
  18.  
  19. An object's instance variables (data) are packaged, or encapsulated, with the object, hidden safely inside the nucleus, safe from access by other objects. The instance variables are surrounded by the object's methods. With certain well-defined exceptions, the object's methods are the only means by which other objects can access or alter its instance variables. In Java, classes can declare their instance variables to be public, in which cases the instance variables are globally accessible--this topic is covered in later in Access Specifiers.
  20.  
  21.  
  22.  
  23. Classes
  24.  
  25. A class defines the instance variables and methods of an object. A class in and of itself is not an object. A class is a template that defines how an object will look and behave when the object is created or instantiated. You can instantiate many objects from one class definition, just as you can construct many houses all the same from a single architect's drawing. The only way you can get concrete objects is by instantiating a previously defined class. Here's the declaration for a very simple class called Point
  26.  
  27.  
  28.  
  29.  
  30.     class Point {
  31.         public float  x;
  32.         public float  y;
  33.     
  34.         Point() {
  35.             x = 0.0;
  36.             y = 0.0;
  37.         }
  38.     }
  39.  
  40.  
  41.  
  42. Methods with the same name as the class as in the code fragment above are called constructors. When you create (instantiate) an object of this class, the constructor method is invoked to perform any initialization that's needed--in this case, to set the instance variables to an initial state.
  43.  
  44. Any other object can now create an instance of Point with a line of code like this:
  45.  
  46.  
  47.  
  48.  
  49.     Point  myPoint;
  50.  
  51.     myPoint = new Point();
  52.  
  53.  
  54.  
  55. Now, you can access the variables of this Point object by referring to the names of the variables, qualified with the name of the object:
  56.  
  57.  
  58.  
  59.  
  60.     myPoint.x = 10.0;
  61.     myPoint.y = 25.7;. 
  62.  
  63.  
  64.  
  65.  
  66.  
  67. Methods and Messaging
  68.  
  69. If an object wants another object to do some work on its behalf, then in the parlance of object-oriented programming, the first object must send a message to the other object. An object sends a message to another object by invoking one of its methods, which look similar to functions in C and C++.
  70.  
  71. In general, methods operate only on the instance variables of a specific instance of the object. However, an object can declare its instance variables to be public, in which case other objects can access the instance variables directly without going through method invocations.
  72.  
  73. Using the message passing paradigms of object-oriented programming, you can build entire networks and webs of objects that pass messages between them to change state. This programming technique is one of the best ways to create complex simulations of real-world systems. 
  74.  
  75.  
  76.  
  77. Constructors and Finalizers
  78.  
  79. When you declare a class in the Java language, you can declare optional contructors that perform initialization when you instantiate objects from that class, and you can declare an optional finalizer that will perform necessary tear down actions when the garbage collector is about to free the object. This minimal code fragment illustrates a constructor.
  80.  
  81.  
  82.  
  83.  
  84.     public final class Integer extends Number {
  85.         private int value
  86.  
  87.         public Integer(int value){ 
  88.             this.value = value;
  89.         }
  90.     } 
  91.  
  92.  
  93.  
  94. This example declares a class called Integer. There is in fact an Integer class in the Java language foundation--it's an object wrapper when you need to encapsulate an integer value inside an object. The public method Integer is the constructor for this class. You would access it in code via a declaration of the form
  95.  
  96.  
  97.  
  98.  
  99.     Integer  myIntegerObject = new Integer(123);
  100.  
  101.  
  102.  
  103. to create a new object of the Integer class initialized to the value 123.
  104.  
  105. By the way, what is the variable this in the above example? It is a special name that refers to this instance of the class--from inside an object, you need a way to refer to the object itself. That's what the this variable achieves.
  106.  
  107. This code fragment illustrates a finalize method in a class. 
  108.  
  109.  
  110.  
  111.  
  112.     /**
  113.       * Close the stream when garbage is collected.
  114.     */  
  115.     protected void finalize() {
  116.         try {
  117.             close();
  118.         } catch (Exception e) {
  119.         }
  120.     } 
  121.  
  122.  
  123.  
  124. This finalize method will be invoked when the object is about to be garbage collected. In the particular code fragment, the finalize method merely closes an I/O file stream that was used by the object to ensure that the file descriptor for the stream is closed. 
  125.  
  126.  
  127.  
  128. Subclassing
  129.  
  130. Subclassing is the mechanism by which new and enhanced objects can be defined in terms of existing objects. One example: a zebra is a horse with stripes. If you wish to create a zebra object, you notice that a zebra is kind of like a horse, only with stripes. In object oriented terms, you'd create a new class called Zebra, which is a subclass of the Horse class. In Java language terms, you'd do something like this:
  131.  
  132.  
  133.  
  134.  
  135.     class Zebra extends Horse {
  136.         Your new instance variables and new methods go here
  137.     }
  138.  
  139.  
  140.  
  141. The definition of Horse, wherever it is, would define all the methods to describe the behavior of a horse--eat, neigh, trot, gallop, buck, and so on. The only method you need to override is the method for drawing the hide. You gain the benefit of already written code that does all the work--you don't have to re-invent the wheel, or in this case, the hoof. The extends keyword tells the Java compiler that Zebra is a subclass of Horse. Zebra is said to be a derived class--it's derived from Horse, which is called a base class.
  142.  
  143. Subclassing enables you to use existing code that's already been developed and, much more important, tested, for a more generic case. You override the parts of the class you need for your specific behavior. Thus, sub-classing gains you re-use of existing code--you save on design, development, and testing. The Java supporting run-time system provides several libraries of utility functions that are tested and are also thread-safe. 
  144.  
  145.  
  146.  
  147. Access Control
  148.  
  149. When you declare a new class in the Java language, you can indicate the level of access permitted to its instance variables and methods. The Java language provides four levels of access specifiers. Three of the levels must be explicitly specified if you wish to use them. They are public, protected, and private.
  150.  
  151. The fourth level doesn't have a name--it's often called "friendly" and is the access level you obtain if you don't specify otherwise. The "friendly" access level indicates that your instance variables and methods are accessible to all objects within the same package, but inaccessible to objects outside the package.
  152.  
  153. public methods and instance variables are available to any other class anywhere. protected means that instance variables and methods so designated are accessible only to subclasses of that class, and nowhere else. private methods and instance variables are accessible only from within the class in which they're declared--they're not available even to their subclasses.
  154.  
  155.  
  156.  
  157. Static and Final Methods and Variables
  158.  
  159. The Java language follows conventions from other object-oriented languages in providing for class methods and class variables. Normally, variables you declare in a class definition are instance variables--there will be one of those variables in every separate object that's created (instantiated) from the class. A class variable, on the other hand, is a variable that's local to the class itself. There's only copy of the variable and it's shared by every object you instantiate from the class. Here's a short code fragment.
  160.  
  161.  
  162.  
  163.  
  164.     class Rectangle extends Object {
  165.         static  final int version = 2;
  166.         static  final int revision = 0;
  167.     } 
  168.  
  169.  
  170.  
  171. The Rectangle class declares two static variables to define the version and revision level of this class. Now, every instance of Rectangle that you create from this class will share these same variables. Notice they're also defined as final because you want them to be constants.
  172.  
  173. Class methods are methods you declare that operate only on instance variables of the class. Class methods can't access instance variables, nor can they invoke instance methods. Like class variables, you declare class methods by defining them as static.
  174.  
  175.  
  176.  
  177.  
  178.  
  179. Abstract Methods
  180.  
  181. Abstract methods are a powerful construct in the object-oriented paradigm. To understand abstract methods, we look at the notion of an abstract superclass. This is a class in which you define methods that aren't actually implemented by that class--they only provide place-holders such that subsequent subclasses can override those methods and supply their actual implementation.
  182.  
  183. This all sounds wonderfully, well, abstract, so why would you need an abstract superclass? Let's look at a concrete example, no pun intended.
  184.  
  185. Suppose you are creating a drawing application. The initial cut of your application can draw rectangles, lines, circles, polygons, and so on. Furthermore, you have a series of operations you can perform on the shapes--move, reshape, rotate, fill color, and so on. You could make each of these graphic shapes a separate class--you'd have a Rectangle class, a Line class, and so on. Each class needs instance variables to define its position, size, color, rotation and so on, which in turn dictates methods to set and get at those variables.
  186.  
  187. At this point, you realize you can collect all the instance variables into a single abstract superclass, and implement most of the methods to manipulate the variables in that abstract superclass. The skeleton of your abstract superclass might look something like this.
  188.  
  189.  
  190.  
  191.  
  192. class Graphic {
  193.     Point p;                            //  position
  194.     float fillcolor;                 //  gray shade of interior
  195.     float linecolor;               //  gray shade of outline
  196.     . . .;                             //  more instance variables
  197.                                            //  more methods
  198.     abstract void drawmyself()    //  do nothing method
  199. }
  200.  
  201.  
  202.  
  203. Now, you can't instantiate the Graphic class. You can only instantiate a subclass of it. When you implement the Rectangle class, you'd subclass Graphic. Within Rectangle, you'd provide a concrete implementation of the drawmyself method that draws a rectangle. You can continue in this way adding new shapes that are subclasses of Graphic, and all you ever need to implement is the method to draw the shape. You gain the benefit of re-using all the code that was defined inside the abstract superclass.
  204.  
  205.  
  206.  
  207. Packages
  208.  
  209. Packages are a Java language construct that gather collections of related classes into a single container. For example, all the Java language I/O system code is collected into a single package. The primary benefit of packages is organizing many class definitions into a single compilation unit. The secondary benefit from the programmer's viewpoint is that the "friendly" instance variables and methods are available to all classes within the same package, but not to classes defined outside the package. 
  210.  
  211. As an example, you could create a rectangle geometry package containing the definitions of a point class and a rectangle class, plus all the operations you'd want to perform on points and rectangles. Within the package, you could have rectangles accessing the "friendly" instance variables of the point class directly, thereby improving the overall performance of the objects. But other classes outside the package would be able to access the internal state of point objects and rectangle objects only by invoking the public methods of the classes. 
  212.  
  213.  
  214. ----------------------------------------------------------------
  215.  
  216.  
  217. 2.3 Features Removed from C and C++
  218.  
  219. The previous sections concentrated on features of the Java language. This section discusses features removed from C and C++ in the design of the Java language. The first step was to eliminate redundancy from C and C++. In many ways, the C language evolved into a collection of overlapping features, providing too many ways to say the same thing, while in many cases not providing needed features. C++, even in an attempt to add "classes in C" merely added more redundancy while retaining the inherent problems of C.
  220.  
  221.  
  222.  
  223. Typedefs, Defines, and the Preprocessor
  224.  
  225. Source code written in the Java language is simple. There is no preprocessor, no #define and related capabilities, no typedef, and absent those features, no longer any need for header files. Instead of header files, Java language interfaces provide the definitions of other classes and their methods. 
  226.  
  227. A major problem with C and C++ is the amount of context you need to understand another programmer's code--you have to read all related header files, all related #defines, and all related typedefs before you can even begin to analyze a program. In a sense, programming in this style essentially results in every programmer inventing a new programming language that's incomprehensible to anybody other than its creator and defeats the goals of good programming practices.
  228.  
  229. You can obtain the effects of #define by using constants. You obtain the effects of typedef by declaring classes--after all, a class effectively declares a new type. You don't need header files because the Java language compiler compiles class definitions into a binary form that retains all the type information through to link time. 
  230.  
  231. By removing all this baggage, the Java language becomes remarkably context free. Programmers can read and understand code and, more importantly, modify and re-use code much faster and easier. 
  232.  
  233.  
  234.  
  235. Structures and Unions
  236.  
  237. The Java language has no structures or unions as complex data types. You don't need structures and unions when you have classes--you can achieve the same effect simply by using instance variables of a class. This code fragment declares Point and Rectangle classes. In C you'd define these as structures. In the Java language, you simply declare a class. You can make the instance variables as private or as public as you wish, depending on how much you wish to hide the details of the implementation. 
  238.  
  239.  
  240.  
  241.  
  242.     class Point extends Object { 
  243.         float  x;
  244.         float  y;
  245.           methods to access the instance variables
  246.     }
  247.     class Rectangle extends Object {
  248.         Point  lowerLeft;
  249.         Point  upperRight;
  250.           methods to access the instance variables
  251.     }
  252.  
  253.  
  254.  
  255.  
  256.  
  257. Functions
  258.  
  259. The Java language has no functions. Object-oriented programming supersedes functional and procedural styles. Mixing the two styles just leads to confusion and dilutes the purity of an object-oriented language. Anything you can do with a function, you can do just as well by defining a class and creating methods for that class. By eliminating functions, the Java language has immensely simplified your job as a programmer--you work only with classes and methods.
  260.  
  261.  
  262.  
  263. Multiple Inheritance and Interfaces
  264.  
  265. The Java language discards multiple inheritance and all the problems it generates. The desirable features of multiple inheritance are provided by interfaces--conceptually similar to Objective C protocols.
  266.  
  267. An interface is not a definition of an object. Rather, it's a definition of a set of methods that one or more objects will implement. An important issue of interfaces is that they declare methods only--in general, no instance variables other than final variables (which are constants) may be defined in interfaces.
  268.  
  269.  
  270.  
  271. Goto Statements Gone
  272.  
  273. The Java language has no goto statement. Studies illustrated that goto is (mis)used more often than not simply "because it's there". Eliminating goto led to a simplification of the language--there are no rules about the effects of gotoing into the middle of a for statement, for example. As mentioned above, multi-level break and continue remove the need for goto statements.
  274.  
  275.  
  276.  
  277. Operator Overloading
  278.  
  279. The Java language has no C++ style operator overloading.
  280.  
  281.  
  282.  
  283. Automatic Coercions
  284.  
  285. The Java language prohibits C and C++ style automatic coercions. If you wish to coerce a data element of one type to a data type that would result in loss of precision, you must do so explicitly by using a cast. Consider this code fragment:
  286.  
  287.  
  288.  
  289.  
  290.  
  291.     int  myInt;
  292.     float  myFloat = 3.14159;
  293.     myInt = myFloat;
  294.  
  295.  
  296.  
  297. The assignment of myFloat to myInt would result in a compiler warning of possible loss of precision and that you should use a cast. Thus, you should re-write the code fragments as:
  298.  
  299.  
  300.  
  301.  
  302.     int  myInt;
  303.     float  myFloat = 3.14159;
  304.     myInt = (int)myFloat;
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311. Pointers
  312.  
  313. Most studies agree that pointers are one of the primary features that enable programmers to put bugs into their code. Given that structures are gone, and arrays and strings are objects, the need for pointers to these constructs goes away. Thus the Java language has no pointers. Any task that would require arrays, structures, and pointers in C can be much more easily and reliably performed in the Java language by declaring objects and arrays of objects.
  314.  
  315.  
  316. ----------------------------------------------------------------
  317.  
  318.  
  319. 2.4 Summary
  320.  
  321. To sum up this chapter, you've by now gained the understanding that the Java language is:
  322.  
  323.  
  324.  
  325. ΓÇóSimple--the number of language constructs you need to understand to get your job done is minimal.
  326.  
  327. ΓÇóObject-oriented--you can develop software using up-to-date software development practices.
  328.  
  329. ΓÇóFamiliar--the Java language "looks like" C and C++ while discarding the overwhelming complexities of those languages.
  330.